home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Ebooks / Thinking in C++ V2 / C26 / CGImap.h < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-25  |  3.4 KB  |  121 lines

  1. //: C26:CGImap.h
  2. // From Thinking in C++, 2nd Edition
  3. // Available at http://www.BruceEckel.com
  4. // (c) Bruce Eckel 1999
  5. // Copyright notice in Copyright.txt
  6. // Tools for extracting and decoding data from 
  7. // from CGI GETs and POSTs.
  8. #include <string>
  9. #include <vector>
  10. #include <iostream>
  11. using namespace std;
  12.  
  13. class CGIpair : public pair<string, string> {
  14. public:
  15.   CGIpair() {}
  16.   CGIpair(string name, string value) {
  17.     first = decodeURLString(name);
  18.     second = decodeURLString(value);
  19.   }
  20.   // Automatic type conversion for boolean test:
  21.   operator bool() const {
  22.     return (first.length() != 0);
  23.   } 
  24. private:  
  25.   static string decodeURLString(string URLstr) {
  26.     const int len = URLstr.length();
  27.     string result;
  28.     for(int i = 0; i < len; i++) {
  29.       if(URLstr[i] == '+')
  30.         result += ' ';
  31.       else if(URLstr[i] == '%') {
  32.         result +=
  33.           translateHex(URLstr[i + 1]) * 16 +
  34.           translateHex(URLstr[i + 2]);
  35.         i += 2; // Move past hex code
  36.       } else // An ordinary character
  37.         result += URLstr[i];
  38.     }
  39.     return result;
  40.   }
  41.   // Translate a single hex character; used by
  42.   // decodeURLString():
  43.   static char translateHex(char hex) {
  44.     if(hex >= 'A')
  45.       return (hex & 0xdf) - 'A' + 10;
  46.     else
  47.       return hex - '0';
  48.   }
  49. };
  50.  
  51. // Parses any CGI query and turns it into an
  52. // STL vector of CGIpair which has an associative
  53. // lookup operator[] like a map. A vector is used
  54. // instead of a map because it keeps the original
  55. // ordering of the fields in the Web page form.
  56. class CGImap : public vector<CGIpair> {
  57.   string gq;
  58.   int index;
  59.   // Prevent assignment and copy-construction:
  60.   void operator=(CGImap&);
  61.   CGImap(CGImap&);
  62. public:
  63.   CGImap(string query): index(0), gq(query){
  64.     CGIpair p;
  65.     while((p = nextPair()) != 0)
  66.       push_back(p); 
  67.   }
  68.   // Look something up, as if it were a map:
  69.   string operator[](const string& key) {
  70.     iterator i = begin();
  71.     while(i != end()) {
  72.       if((*i).first == key)
  73.         return (*i).second;
  74.       i++;
  75.     }
  76.     return string(); // Empty string == not found
  77.   }
  78.   void dump(ostream& o, string nl = "<br>") {
  79.     for(iterator i = begin(); i != end(); i++) {
  80.       o << (*i).first << " = "
  81.         << (*i).second << nl;
  82.     }
  83.   }
  84. private:
  85.   // Produces name-value pairs from the query 
  86.   // string. Returns an empty Pair when there's 
  87.   // no more query string left:
  88.   CGIpair nextPair() {
  89.     if(gq.length() == 0)
  90.       return CGIpair(); // Error, return empty
  91.     if(gq.find('=') == -1)
  92.       return CGIpair(); // Error, return empty
  93.     string name = gq.substr(0, gq.find('='));
  94.     gq = gq.substr(gq.find('=') + 1);
  95.     string value = gq.substr(0, gq.find('&'));
  96.     gq = gq.substr(gq.find('&') + 1);
  97.     return CGIpair(name, value);
  98.   }
  99. };
  100.  
  101. // Helper class for getting POST data:
  102. class Post : public string {
  103. public: 
  104.   Post() {
  105.     // For a CGI "POST," the server puts the
  106.     // length of the content string in the 
  107.     // environment variable CONTENT_LENGTH:
  108.     char* clen = getenv("CONTENT_LENGTH");
  109.     if(clen == 0) {
  110.       cout << "Zero CONTENT_LENGTH, Make sure "
  111.         "this is a POST and not a GET" << endl;
  112.       return;
  113.     }
  114.     int len = atoi(clen);
  115.     char* s = new char[len];
  116.     cin.read(s, len); // Get the data
  117.     append(s, len); // Add it to this string
  118.     delete []s;
  119.   }
  120. }; ///:~
  121.